Tool
A tool the LLM can call — application code constructs these via the top-level tool (single-value) or streamingTool (Flow) factories.
Per invariant I-2, tools use inputSchema (v6) — never parameters (v5, removed). Per I-8 tools are stateless: inputs in, outputs out, no shared mutable state.
Type Parameters
Application-defined input type, must be @Serializable. The model produces JSON matching its schema; the agent deserializes via inputSerializer before calling executor.
Application-defined output type, must be @Serializable. Serialized into the model's tool-result message via outputSerializer, or summarized via toModelOutput if the raw output would be too verbose for the model.
Caller-supplied typed context propagated through the whole loop (set via callOptionsSchema, accessed inside the executor as this.context).
The internal executor always returns a Flow (the v6 alignment per tool.ts:68-71's AsyncIterable<OUTPUT> shape). Single-value tools built via tool wrap their suspend (TInput) -> TOutput body in a one-emission flow; streaming tools built via streamingTool pass their Flow body straight through. The agent loop's tool dispatcher collects with one-step lookahead — non-final emissions become StreamEvent.ToolResult(preliminary = true), the last emission is the final result that lands in the model's message log.
Constructors
Properties
Few-shot example inputs encoded as JSON strings. Mirrors v6's tool.inputExamples (per historical parity gap #19). Disproportionate quality lift on small models — Gemma 4 E2B's tool-call accuracy notably improves with 2-3 in-tool examples. ToolSet.descriptors inlines these into the description as Example: <json> so every provider sees them (most don't expose a separate examples field).
Application-defined metadata bag. Mirrors v6's tool.metadata (per historical parity gap #34). Opaque to the loop — consumers (logger middleware, telemetry, host-side gating) can read it via ToolSet.byName. Examples: feature-flag key, billing tier, owning team. Empty by default.
Approval gate. Per historical parity gap #17, the predicate receives ToolPredicateOptions (toolCallId + messages + experimental_context) — not just context. Lets the gate decide based on conversation history or call identity.
Lifecycle hook — fired after the streamed JSON has parsed successfully into the typed TInput, just before executor runs. Mirrors v6's tool.onInputAvailable.
Lifecycle hook — fired as the model streams the tool's input JSON token-by-token (StreamEvent.ToolInputDelta). The accumulated input isn't yet valid JSON; this is for raw-character pre-warm.
Lifecycle hook — fired when the model commits to calling this tool (StreamEvent.ToolInputStart arrives). Mirrors v6's tool.onInputStart (per historical parity gap #18). Lets a tool pre-warm: UI spinner, cache priming, etc.
Provider-specific config for this tool, sent to the model on the wire (e.g. Anthropic cache_control). Distinct from metadata, which is host-side only. Mirrors v6's tool.providerOptions. Empty by default.
Model-visible summary. Per historical parity gaps #17 + #14, the callback receives both the typed output AND ToolPredicateOptions; returns a structured ToolResultOutput (Text / Json / Error) instead of a bare String. The agent loop bridges each variant to the wire-format ContentPart.ToolResult.modelVisible (+ isError).